<template>
	<div>
		<div class="container">
			<div class="handle-box">
				<!-- 查询条件，绑定在 query 对象中
					请求查询接口时一并传入后端接口
					属性名需要与后端接收参数的实体类属性名相同，否则参数接收不到 -->
				<el-select v-model="query.address" placeholder="地址" class="handle-select mr10">
					<el-option key="1" label="广东省" value="广东省"></el-option>
					<el-option key="2" label="湖南省" value="湖南省"></el-option>
				</el-select>
				<el-input v-model="query.title" placeholder="歌单名称/风格" class="handle-input mr10"></el-input>
				<el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button>
				<el-button type="primary" :icon="Plus" @click="handleAdd">新增</el-button>
			</div>
			<!-- :data 绑定的是需要渲染的数据列表（数组），即：tableData 是由列表查询接口返回的数组 -->
			<el-table :data="tableData" border class="table" ref="multipleTable" header-cell-class-name="table-header">
				<!-- el-table-column 为列组件，主要渲染列数据。
					prop 属性来对应对象中的键名即可填入数据，
					用 label 属性来定义表格的列名。 
					可以使用 width 属性来定义列宽。 -->
				<el-table-column type="index" label="序号" width="55" align="center"></el-table-column>
				<!-- <el-table-column prop="id" label="ID" width="55" align="center"></el-table-column> -->
				<el-table-column prop="title" label="歌单名称"></el-table-column>
				<!-- <el-table-column prop="pic" label="歌单头像"></el-table-column> -->
				<el-table-column label="头像(查看大图)" align="center">
					<template #default="scope">
						<el-image
							class="table-td-thumb"
							:src="getImageUrl(scope.row.pic)"
							:z-index="10"
							style="width: 100px; height: 100px"
							:preview-src-list="[scope.row.pic]"
							fit="fill"
							preview-teleported
						>
						</el-image>
					</template>
				</el-table-column>
				<el-table-column prop="style" label="风格"></el-table-column>
				<el-table-column prop="introduction" width="220" label="简介" :formatter="getIntroduction"></el-table-column>
				<!-- :formatter="(row:any) => getDictLabel('sys_del_flag', row.delFlag)" -->
				<el-table-column prop="delFlag" label="是否删除" align="center" 
					>
					<template #default="scope">
						{{ showLabel('sys_del_flag', scope.row.delFlag) }}
					</template>
				</el-table-column>
				<el-table-column label="操作" width="120" align="center">
					<template #default="scope">
						<el-button text :icon="Edit" 
							@click="handleEdit(scope.$index, scope.row)" v-permiss="15">
							编辑
						</el-button>
						<el-button text :icon="Delete" class="red" 
							@click="handleDelete(scope.row)" v-permiss="16">
							删除
						</el-button>
					</template>
				</el-table-column>
			</el-table>
			<!-- 
				分页 current-page、page-size（每页条数）、total（总条数）
				layout 用于配置分页导航条显示的内容：total（总记录数）, prev（上一页）, pager（分页列表）, next（下一页）
				当用户点击分页导航条中的按钮（current-page 改变时触发）时触发 current-page 事件，执行查询
			 -->
			<div class="pagination">
				<el-pagination
					background
					layout="total, prev, pager, next"
					:current-page="query.pageNum"
					:page-size="query.pageSize"
					:total="pageTotal"
					@current-change="handlePageChange"
				></el-pagination>
			</div>
		</div>

		<!-- 编辑弹出框，通过 editVisible 控制是否显示，在用户点击“新增”、“编辑”按钮时打开。 -->
		<el-dialog :title="dialogTitle" v-model="editVisible" width="80%">
			<el-form label-width="70px">
				<!-- 需要添加、修改的内容绑定在 from 对象中，添加、修改时同时提交至后端接口 -->
				<el-form-item label="歌单名称">
					<el-input v-model="form.title"></el-input>
				</el-form-item>
				<el-form-item label="风格">
					<el-input v-model="form.style"></el-input>
				</el-form-item>
				<el-form-item label="图片">
					<!-- :on-change="handlImageChange" -->
					<el-upload style="display: display;"
						class="avatar-uploader"
						:action="serverUrl + '/upload/image'"
						:show-file-list="false"
						:on-success="handleAvatarSuccess"
						:before-upload="beforeAvatarUpload"
						>
						<img v-if="form.pic" :src="getImageUrl(form.pic)" class="avatar" />
    					<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
					</el-upload>
					<!-- <el-image @clikc="toSelectFile" style="width: 100px; height: 100px" :src="picUrl" :fit="fit" /> -->
				</el-form-item>
				<el-form-item label="歌单简介">
					<el-input v-model="form.introduction" type="textarea" :rows="5"></el-input>
				</el-form-item>
			</el-form>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="editVisible = false">取 消</el-button>
					<!-- 点击“确定”按钮触发 saveEdit 函数，在该函数中实现添加、修改业务。 -->
					<el-button type="primary" @click="saveEdit">确 定</el-button>
				</span>
			</template>
		</el-dialog>
	</div>
</template>

<script setup lang="ts" name="basetable">
import { ref, reactive } from 'vue';
import { ElMessage, ElMessageBox, formItemValidateStates } from 'element-plus';
import { Delete, Edit, Search, Plus, List } from '@element-plus/icons-vue';
import { getImageUrl } from '../utils/index';
import { getDictLabel } from '../api/index';
import type { UploadProps } from 'element-plus'
import {default as http, serverUrl} from '../utils/request'

//约束列表显示内容（属性）
interface TableItem {
	id: number;
	title: string;
	pic: string;
	style: string;
	introduction: string;
}

/* 查询参数，除显示查询条件（例如地址 address、歌单名称 title等）外还包括：
	分页信息（pageNum 要显示第几页，pageSize 每页显示记录数）
*/
const query = reactive({
	address: '',
	title: '',	//歌单名称/风格
	pageNum: 1,
	pageSize: 5
});
//要显示的数据数组
const tableData = ref<TableItem[]>([

]);
// List<User> list = new List<User>();
// list.add(Student);
//总记录数，接口返回数据后需要将总记录数赋给该变量，用于显示分页导航条
const pageTotal = ref(0);
// 请求接口获取表格数据
const getData = () => {
	//这里请求地址为：/admin/songlist，params为 query 参数，拼接在url中的？后边，
	//例如： http://localhost:8080/admin/songlist?address=宁夏&title=华语&pageNum=1&pageSize=10
	http.get("/admin/songlist", {
		params: query
	}).then((res: any) => {
		console.log('获取用户信息 res = ', res)
		tableData.value = res.data.data.list;	//将接口返回的数组赋值给 tableData
		pageTotal.value = res.data.data.total;	//赋值本次查询总记录数
	}).catch((err: any) => {
		console.log('获取用户信息 res = ', err)
	})
};
//页面加载后执行列表查询方法
getData();

// 查询操作：用户点击“搜索”时执行
const handleSearch = () => {
	query.pageNum = 1;
	getData();
};
// 分页导航：用户点击分页导航条中的按钮时触发
const handlePageChange = (val: number) => {
	query.pageNum = val;
	getData();
};

//上传文件前回调该方法，用于校验文件格式、大小；
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  console.log('beforeAvatarUpload = ', rawFile);
  if (rawFile.type !== 'image/jpeg') {
    ElMessage.error('Avatar picture must be JPG format!')
    return false
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('Avatar picture size can not exceed 2MB!')
    return false
  }
  return true
}

//上传成功：会请求 action 属性配置的URL，成功后回调该方法；
const handleAvatarSuccess: UploadProps['onSuccess'] = (
  response,
  uploadFile
) => {
	//这里
  console.log('handleAvatarSuccess = ', response, ' uploadFile = ',uploadFile);
  if("200" === response.code){
	// form.pic = URL.createObjectURL(uploadFile.raw!)
	form.pic = response.url;//成功后将服务器返回的 url 赋值给 form.pic
  }
}

// 删除操作
const handleDelete = (row: any) => {
	// 二次确认删除
	ElMessageBox.confirm(`确定要删除歌单【${row.title}】吗？`, '提示', {
		type: 'warning'
	})
	.then(() => {//用户点击确定按钮
		http.delete("/admin/songlist/" + row.id)
		.then((res) => {
			console.log('删除返回值：', res);
			if(res.data.code === 200){	//修改成功
				ElMessage.success(`删除成功`);
				getData();
			}
		}).catch((err) => {
			console.log('修改失败：', err);
			ElMessage.error(`修改失败`);
		});
	})
	.catch(() => {//点击取消按钮

	});
};

// 表格编辑时弹窗和保存
const dialogTitle = ref('新增');
const editVisible = ref(false);
let form = reactive({
	id: '',
	title: '',
	style: '',
	pic: '',
	introduction: ''
});
const handleAdd = () => {
	dialogTitle.value = "新增";
	form.id = '';
	form.title = '';
	form.style = '';
	form.pic = '';
	form.introduction = '';
	editVisible.value = true;
};
const handleEdit = (index: number, row: any) => {
	dialogTitle.value = "编辑";
	form.id = row.id;
	form.title = row.title;
	form.style = row.style;
	form.pic = row.pic;
	form.introduction = row.introduction;
	editVisible.value = true;
};
const saveEdit = () => {
	// ElMessage.success(`修改第 ${idx + 1} 行成功`);
	// tableData.value[idx].name = form.name;
	// tableData.value[idx].address = form.address;
	if(!form.id){	//form.id 为空：新增
		console.log('新增', form);
		http.post("/admin/songlist", form)
		.then((res) => {
			console.log('新增返回值：', res);
			if(res.data.code === 200){	//新增成功
				ElMessage.success(`新增成功`);
				editVisible.value = false;
				getData();
			}
		}).catch((err) => {
			console.log('新增失败：', err);
			ElMessage.error(`新增失败`);
		});
	}else{ //修改
		console.log('修改', form);
		http.put("/admin/songlist", form)
		.then((res) => {
			console.log('修改返回值：', res);
			if(res.data.code === 200){	//修改成功
				ElMessage.success(`修改成功`);
				editVisible.value = false;
				getData();
			}
		}).catch((err) => {
			console.log('修改失败：', err);
			ElMessage.error(`修改失败`);
		});
	}
};

// row(行对象), column（列对象）, cellValue（当前单元格内容，简介）, index（下标）
const getIntroduction = (row: any, column: any, cellValue: any, index: any) => {
	console.log("格式化简介内容", row, column, cellValue.length, index);
	if(cellValue.length > 50){
		return cellValue.substr(0, 50) + '...';
	}
	return cellValue;
}
//已封装至 /utils/index.ts 文件中。
// const getImageUrl = (picUrl: any) => {
// 	return "http://localhost:8080" + picUrl;
// }

const showLabel = async (dictType: string, dictValue: string) => {
	let label:any = await "";
	let res = await getDictLabel(dictType, dictValue).then(res => {
		// return res;
		console.log('then', res)
		label = res;
	}).catch((err) => {
		console.log('catch', err)
		// return err;
	});
	console.log("showlabel = ", res);
	return label;
}

</script>

<style scoped>
.handle-box {
	margin-bottom: 20px;
}

.handle-select {
	width: 120px;
}

.handle-input {
	width: 300px;
}
.table {
	width: 100%;
	font-size: 14px;
}
.red {
	color: #ff0000;
}
.mr10 {
	margin-right: 10px;
}
.table-td-thumb {
	display: block;
	margin: auto;
	width: 40px;
	height: 40px;
}

:deep(.el-upload){
  width: 178px;
}

.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
